home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / DB / DataObject / Generator.php < prev   
PHP Script  |  2004-10-01  |  24KB  |  739 lines

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP Version 4                                                        |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2003 The PHP Group                                |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2.02 of the PHP license,      |
  8. // | that is bundled with this package in the file LICENSE, and is        |
  9. // | available at through the world-wide-web at                           |
  10. // | http://www.php.net/license/2_02.txt.                                 |
  11. // | If you did not receive a copy of the PHP license and are unable to   |
  12. // | obtain it through the world-wide-web, please send a note to          |
  13. // | license@php.net so we can mail you a copy immediately.               |
  14. // +----------------------------------------------------------------------+
  15. // | Author:  Alan Knowles <alan@akbkhome.com>
  16. // +----------------------------------------------------------------------+
  17. // $Id: Generator.php,v 1.71 2004/08/11 06:52:35 alan_k Exp $
  18.  
  19. /**
  20.  * Generation tools for DB_DataObject
  21.  *
  22.  * Config _$ptions
  23.  * [DB_DataObject_Generator]
  24.  * ; optional default = DB/DataObject.php
  25.  * extends_location =
  26.  * ; optional default = DB_DataObject
  27.  * extends =
  28.  * ; leave blank to not generate template stuff.
  29.  * make_template = display,list,edit
  30.  *
  31.  * ; options for Template Generation (using FlexyTemplate
  32.  * [DB_DataObject_Generator_Template_Flexy]
  33.  * templateDir = /home/xxx/templates
  34.  * compileDir = /home/xxx/compiled",
  35.  * filters   = php,simpletags,bodyonly
  36.  * forceCompile = 0
  37.  *
  38.  * ; fileds to flags as hidden for template generation(preg_match format)
  39.  * hideFields = password
  40.  * ; fields to flag as read only.. (preg_match format)
  41.  * readOnlyFields = created|person_created|modified|person_modified
  42.  * ; fields to flag as links (from lists->edit/view) (preg_match formate)
  43.  * linkFields = id|username|name
  44.  * ; alter the extends field when updating a class (defaults to only replacing DB_DataObject)
  45.  * generator_class_rewrite = ANY|specific_name   // default is DB_DataObject
  46.  *
  47.  * @package  DB_DataObject
  48.  * @category DB
  49.  */
  50.  
  51. /**
  52.  * Needed classes
  53.  */
  54. require_once 'DB/DataObject.php';
  55. //require_once('Config.php');
  56.  
  57. /**
  58.  * Generator class
  59.  *
  60.  * @package DB_DataObject
  61.  */
  62. class DB_DataObject_Generator extends DB_DataObject
  63. {
  64.     /* =========================================================== */
  65.     /*  Utility functions - for building db config files           */
  66.     /* =========================================================== */
  67.  
  68.     /**
  69.      * Array of table names
  70.      *
  71.      * @var array
  72.      * @access private
  73.      */
  74.     var $tables;
  75.  
  76.     /**
  77.      * associative array table -> array of table row objects
  78.      *
  79.      * @var array
  80.      * @access private
  81.      */
  82.     var $_definitions;
  83.  
  84.     /**
  85.      * active table being output
  86.      *
  87.      * @var string
  88.      * @access private
  89.      */
  90.     var $table; // active tablename
  91.  
  92.  
  93.     /**
  94.      * The 'starter' = call this to start the process
  95.      *
  96.      * @access  public
  97.      * @return  none
  98.      */
  99.     function start()
  100.     {
  101.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  102.         $databases = array();
  103.         foreach($options as $k=>$v) {
  104.             if (substr($k,0,9) == 'database_') {
  105.                 $databases[substr($k,9)] = $v;
  106.             }
  107.         }
  108.  
  109.         if (@$options['database']) {
  110.             require_once 'DB.php';
  111.             $dsn = DB::parseDSN($options['database']);
  112.             if (!isset($database[$dsn['database']])) {
  113.                 $databases[$dsn['database']] = $options['database'];
  114.             }
  115.         }
  116.  
  117.         foreach($databases as $databasename => $database) {
  118.             if (!$database) continue;
  119.             $this->debug("CREATING FOR $databasename\n");
  120.             $class = get_class($this);
  121.             $t = new $class;
  122.             $t->_database_dsn = $database;
  123.             $t->_database = $databasename;
  124.             $t->_createTableList();
  125.  
  126.             foreach(get_class_methods($class) as $method) {
  127.                 if (substr($method,0,8 ) != 'generate') {
  128.                     continue;
  129.                 }
  130.                 $this->debug("calling $method");
  131.                 $t->$method();
  132.             }
  133.         }
  134.         $this->debug("DONE\n\n");
  135.     }
  136.  
  137.     /**
  138.      * Output File was config object, now just string
  139.      * Used to generate the Tables
  140.      *
  141.      * @var    string outputbuffer for table definitions
  142.      * @access private
  143.      */
  144.     var $_newConfig;
  145.  
  146.     /**
  147.      * Build a list of tables;
  148.      * Currently this is very Mysql Specific - ideas for more generic stiff welcome
  149.      *
  150.      * @access  private
  151.      * @return  none
  152.      */
  153.     function _createTableList()
  154.     {
  155.         $this->_connect();
  156.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  157.  
  158.         $__DB= &$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5];
  159.  
  160.         $this->tables = $__DB->getListOf('tables');
  161.         
  162.         if (is_a($this->tables , 'PEAR_Error')) {
  163.             return PEAR::raiseError($this->tables->toString(), null, PEAR_ERROR_DIE);
  164.         }
  165.         // build views as well if asked to.
  166.         if (!empty($options['build_views'])) {
  167.             $this->tables = array_merge ($this->tables, $__DB->getListOf('views'));
  168.         }
  169.         
  170.         
  171.         // declare a temporary table to be filled with matching tables names
  172.         $tmp_table = array();
  173.  
  174.  
  175.         foreach($this->tables as $table) {
  176.             if (isset($options['generator_include_regex']) &&
  177.                 !preg_match($options['generator_include_regex'],$table)) {
  178.                     continue;
  179.             } else if (isset($options['generator_exclude_regex']) &&
  180.                 preg_match($options['generator_exclude_regex'],$table)) {
  181.                     continue;
  182.             }
  183.             
  184.             // we find a matching table, just  store it into a temporary array
  185.             $tmp_table[] = $table;            
  186.  
  187.             $defs =  $__DB->tableInfo($table);
  188.             if (is_a($defs,'PEAR_Error')) {
  189.                 echo $defs->toString();
  190.                 exit;
  191.             }
  192.             // cast all definitions to objects - as we deal with that better.
  193.             foreach($defs as $def) {
  194.                 if (is_array($def)) {
  195.                     $this->_definitions[$table][] = (object) $def;
  196.                 }
  197.             }
  198.         }
  199.         // the temporary table array is now the right one (tables names matching 
  200.         // with regex expressions have been removed)
  201.         $this->tables = $tmp_table;         
  202.         //print_r($this->_definitions);
  203.     }
  204.  
  205.     /**
  206.      * Auto generation of table data.
  207.      *
  208.      * it will output to db_oo_{database} the table definitions
  209.      *
  210.      * @access  private
  211.      * @return  none
  212.      */
  213.     function generateDefinitions()
  214.     {
  215.         $this->debug("Generating Definitions file:        ");
  216.         if (!$this->tables) {
  217.             $this->debug("-- NO TABLES -- \n");
  218.             return;
  219.         }
  220.  
  221.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  222.  
  223.  
  224.         //$this->_newConfig = new Config('IniFile');
  225.         $this->_newConfig = '';
  226.         foreach($this->tables as $this->table) {
  227.             $this->_generateDefinitionsTable();
  228.         }
  229.         $this->_connect();
  230.         // dont generate a schema if location is not set
  231.         // it's created on the fly!
  232.         if (!@$options['schema_location'] && @!$options["ini_{$this->_database}"] ) {
  233.             return;
  234.         }
  235.         $base =  @$options['schema_location'];
  236.         if (isset($options["ini_{$this->_database}"])) {
  237.             $file = $options["ini_{$this->_database}"];
  238.         } else {
  239.             $file = "{$base}/{$this->_database}.ini";
  240.         }
  241.         
  242.         if (!file_exists(dirname($file))) {
  243.             require_once 'System.php';
  244.             System::mkdir(array('-p','-m',0755,dirname($file)));
  245.         }
  246.         $this->debug("Writing ini as {$file}\n");
  247.         touch($file);
  248.         //print_r($this->_newConfig);
  249.         $fh = fopen($file,'w');
  250.         fwrite($fh,$this->_newConfig);
  251.         fclose($fh);
  252.         //$ret = $this->_newConfig->writeInput($file,false);
  253.  
  254.         //if (PEAR::isError($ret) ) {
  255.         //    return PEAR::raiseError($ret->message,null,PEAR_ERROR_DIE);
  256.         // }
  257.     }
  258.  
  259.     /**
  260.      * The table geneation part
  261.      *
  262.      * @access  private
  263.      * @return  tabledef and keys array.
  264.      */
  265.     function _generateDefinitionsTable()
  266.     {
  267.         global $_DB_DATAOBJECT;
  268.         
  269.         $defs = $this->_definitions[$this->table];
  270.         $this->_newConfig .= "\n[{$this->table}]\n";
  271.         $keys_out =  "\n[{$this->table}__keys]\n";
  272.         $keys_out_primary = '';
  273.         $keys_out_secondary = '';
  274.         if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) {
  275.             echo "TABLE STRUCTURE FOR {$this->table}\n";
  276.             print_r($defs);
  277.         }
  278.         $DB = $this->getDatabaseConnection();
  279.         $dbtype = $DB->phptype;
  280.         
  281.         $ret = array(
  282.                 'table' => array(),
  283.                 'keys' => array(),
  284.             );
  285.             
  286.         $ret_keys_primary = array();
  287.         $ret_keys_secondary = array();
  288.         
  289.         
  290.         
  291.         foreach($defs as $t) {
  292.              
  293.             $n=0;
  294.  
  295.             switch (strtoupper($t->type)) {
  296.  
  297.                 case 'INT':
  298.                 case 'INT2':    // postgres
  299.                 case 'INT4':    // postgres
  300.                 case 'INT8':    // postgres
  301.                 case 'SERIAL4': // postgres
  302.                 case 'SERIAL8': // postgres
  303.                 case 'INTEGER':
  304.                 case 'TINYINT':
  305.                 case 'SMALLINT':
  306.                 case 'MEDIUMINT':
  307.                 case 'BIGINT':
  308.                     $type = DB_DATAOBJECT_INT;
  309.                     if ($t->len == 1) {
  310.                         $type +=  DB_DATAOBJECT_BOOL;
  311.                     }
  312.                     break;
  313.                
  314.                 case 'REAL':
  315.                 case 'DOUBLE':
  316.                 case 'FLOAT':
  317.                 case 'FLOAT8': // double precision (postgres)
  318.                 case 'DECIMAL':
  319.                 case 'NUMERIC':
  320.                     $type = DB_DATAOBJECT_INT; // should really by FLOAT!!! / MONEY...
  321.                     break;
  322.                     
  323.                 case 'YEAR':
  324.                     $type = DB_DATAOBJECT_INT; 
  325.                     break;
  326.                     
  327.                 case 'BIT':
  328.                 case 'BOOL':   
  329.                 case 'BOOLEAN':   
  330.                 
  331.                     $type = DB_DATAOBJECT_BOOL;
  332.                     // postgres needs to quote '0'
  333.                     if ($dbtype == 'pgsql') {
  334.                         $type +=  DB_DATAOBJECT_STR;
  335.                     }
  336.                     break;
  337.                     
  338.                 case 'STRING':
  339.                 case 'CHAR':
  340.                 case 'VARCHAR':
  341.                 case 'VARCHAR2':
  342.                 case 'TINYTEXT':
  343.                 case 'TEXT':
  344.                 case 'MEDIUMTEXT':
  345.                 case 'LONGTEXT':
  346.                 case 'ENUM':
  347.                 case 'SET':         // not really but oh well
  348.                 case 'TIMESTAMPTZ': // postgres
  349.                 case 'BPCHAR':      // postgres
  350.                 case 'INTERVAL':    // postgres (eg. '12 days')
  351.                 
  352.                 case 'CIDR':        // postgres IP net spec
  353.                 case 'INET':        // postgres IP
  354.                 case 'MACADDR':     // postgress network Mac address.
  355.                 
  356.                 
  357.                     $type = DB_DATAOBJECT_STR;
  358.                     break;
  359.                     
  360.                 case 'DATE':    
  361.                     $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE;
  362.                     break;
  363.                     
  364.                 case 'TIME':    
  365.                     $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_TIME;
  366.                     break;    
  367.                     
  368.                 
  369.                 case 'DATETIME': 
  370.                      
  371.                     $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME;
  372.                     break;    
  373.                     
  374.                 case 'TIMESTAMP': // do other databases use this???
  375.                     
  376.                     $type = ($dbtype == 'mysql') ?
  377.                         DB_DATAOBJECT_MYSQLTIMESTAMP : 
  378.                         DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME;
  379.                     break;    
  380.                     
  381.                     
  382.                 case 'TINYBLOB':
  383.                 case 'BLOB':       /// these should really be ignored!!!???
  384.                 case 'MEDIUMBLOB':
  385.                 case 'LONGBLOB':
  386.                 case 'BYTEA':   // postgres blob support..
  387.                     $type = DB_DATAOBJECT_STR + DB_DATAOBJECT_BLOB;
  388.                     break;
  389.                     
  390.                     
  391.             }
  392.             
  393.             
  394.             if (!strlen(trim($t->name))) {
  395.                 continue;
  396.             }
  397.             
  398.             if (preg_match('/not_null/i',$t->flags)) {
  399.                 $type += DB_DATAOBJECT_NOTNULL;
  400.             }
  401.             
  402.             $this->_newConfig .= "{$t->name} = $type\n";
  403.             $ret['table'][$t->name] = $type;
  404.             // i've no idea if this will work well on other databases?
  405.             // only use primary key or nextval(), cause the setFrom blocks you setting all key items...
  406.             // if no keys exist fall back to using unique
  407.             //echo "\n{$t->name} => {$t->flags}\n";
  408.             if (preg_match("/(auto_increment|nextval\()/i",rawurldecode($t->flags))) {
  409.                 // native sequences = 2
  410.                 $keys_out_primary .= "{$t->name} = N\n";
  411.                 $ret_keys_primary[$t->name] = 'N';
  412.             } else if (preg_match("/(primary|unique)/i",$t->flags)) {
  413.                 // keys.. = 1
  414.                 $keys_out_secondary .= "{$t->name} = K\n";
  415.                 $ret_keys_secondary[$t->name] = 'K';
  416.             }
  417.             
  418.             
  419.             
  420.  
  421.         }
  422.         
  423.         $this->_newConfig .= $keys_out . (empty($keys_out_primary) ? $keys_out_secondary : $keys_out_primary);
  424.         $ret['keys'] = empty($keys_out_primary) ? $ret_keys_secondary : $ret_keys_primary;
  425.         
  426.         if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) {
  427.             print_r(array("dump for {$this->table}", $ret));
  428.         }
  429.         
  430.         return $ret;
  431.         
  432.         
  433.     }
  434.  
  435.     /*
  436.      * building the class files
  437.      * for each of the tables output a file!
  438.      */
  439.     function generateClasses()
  440.     {
  441.         //echo "Generating Class files:        \n";
  442.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  443.         $base = $options['class_location'];
  444.         if (!file_exists($base)) {
  445.             require_once 'System.php';
  446.             System::mkdir(array('-p',$base));
  447.         }
  448.         $class_prefix  = $options['class_prefix'];
  449.         if ($extends = @$options['extends']) {
  450.             $this->_extends = $extends;
  451.             $this->_extendsFile = $options['extends_location'];
  452.         }
  453.  
  454.         foreach($this->tables as $this->table) {
  455.             $this->table = trim($this->table);
  456.             $this->classname = $class_prefix.preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table));
  457.             $i = '';
  458.             $outfilename = "{$base}/".preg_replace('/[^A-Z0-9]/i','_',ucfirst($this->table)).".php";
  459.             if (file_exists($outfilename))
  460.                 $i = implode('',file($outfilename));
  461.             $out = $this->_generateClassTable($i);
  462.             $this->debug( "writing $this->classname\n");
  463.             $fh = fopen($outfilename, "w");
  464.             fputs($fh,$out);
  465.             fclose($fh);
  466.         }
  467.         //echo $out;
  468.     }
  469.  
  470.     /**
  471.      * class being extended (can be overridden by [DB_DataObject_Generator] extends=xxxx
  472.      *
  473.      * @var    string
  474.      * @access private
  475.      */
  476.     var $_extends = 'DB_DataObject';
  477.  
  478.     /**
  479.      * line to use for require('DB/DataObject.php');
  480.      *
  481.      * @var    string
  482.      * @access private
  483.      */
  484.     var $_extendsFile = "DB/DataObject.php";
  485.  
  486.     /**
  487.      * class being generated
  488.      *
  489.      * @var    string
  490.      * @access private
  491.      */
  492.     var $_className;
  493.  
  494.     /**
  495.      * The table class geneation part - single file.
  496.      *
  497.      * @access  private
  498.      * @return  none
  499.      */
  500.     function _generateClassTable($input = '')
  501.     {
  502.         // title = expand me!
  503.         $foot = "";
  504.         $head = "<?php\n/**\n * Table Definition for {$this->table}\n */\n";
  505.         // requires
  506.         $head .= "require_once '{$this->_extendsFile}';\n\n";
  507.         // add dummy class header in...
  508.         // class
  509.         $head .= "class {$this->classname} extends {$this->_extends} \n{";
  510.  
  511.         $body =  "\n    ###START_AUTOCODE\n";
  512.         $body .= "    /* the code below is auto generated do not remove the above tag */\n\n";
  513.         // table
  514.         $padding = (30 - strlen($this->table));
  515.         if ($padding < 2) $padding =2;
  516.         $p =  str_repeat(' ',$padding) ;
  517.         $body .= "    var \$__table = '{$this->table}';  {$p}// table name\n";
  518.         
  519.         
  520.         // if we are using the option database_{databasename} = dsn
  521.         // then we should add var $_database = here
  522.         // as database names may not always match.. 
  523.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  524.         if (isset($options["database_{$this->_database}"])) {
  525.             $body .= "    var \$_database = '{$this->_database}';  {$p}// database name (used with database_{*} config)\n";
  526.         }
  527.         
  528.         
  529.         
  530.         
  531.         $defs = $this->_definitions[$this->table];
  532.  
  533.         // show nice information!
  534.         $connections = array();
  535.         $sets = array();
  536.         foreach($defs as $t) {
  537.             if (!strlen(trim($t->name))) {
  538.                 continue;
  539.             }
  540.             $padding = (30 - strlen($t->name));
  541.             if ($padding < 2) $padding =2;
  542.             $p =  str_repeat(' ',$padding) ;
  543.             $body .="    var \${$t->name};  {$p}// {$t->type}({$t->len})  {$t->flags}\n";
  544.             // can not do set as PEAR::DB table info doesnt support it.
  545.             //if (substr($t->Type,0,3) == "set")
  546.             //    $sets[$t->Field] = "array".substr($t->Type,3);
  547.             $body .= $this->derivedHookVar($t,$padding);
  548.         }
  549.  
  550.         // THIS IS TOTALLY BORKED old FC creation
  551.         // IT WILL BE REMOVED!!!!! in DataObjects 1.6
  552.         // grep -r __clone * to find all it's uses
  553.         // and replace them with $x = clone($y);
  554.         // due to the change in the PHP5 clone design.
  555.         
  556.         if ( substr(phpversion(),0,1) < 5) {
  557.             $body .= "\n";
  558.             $body .= "    /* ZE2 compatibility trick*/\n";
  559.             $body .= "    function __clone() { return \$this;}\n";
  560.         }
  561.  
  562.         // simple creation tools ! (static stuff!)
  563.         $body .= "\n";
  564.         $body .= "    /* Static get */\n";
  565.         $body .= "    function staticGet(\$k,\$v=NULL) { return DB_DataObject::staticGet('{$this->classname}',\$k,\$v); }\n";
  566.  
  567.         /*
  568.         theoretically there is scope here to introduce 'list' methods
  569.         based up 'xxxx_up' column!!! for heiracitcal trees..
  570.         */
  571.  
  572.         // set methods
  573.         //foreach ($sets as $k=>$v) {
  574.         //    $kk = strtoupper($k);
  575.         //    $body .="    function getSets{$k}() { return {$v}; }\n";
  576.         //}
  577.         $body .= $this->derivedHookFunctions();
  578.  
  579.         $body .= "\n    /* the code above is auto generated do not remove the tag below */";
  580.         $body .= "\n    ###END_AUTOCODE\n";
  581.  
  582.         $foot .= "}\n";
  583.         $full = $head . $body . $foot;
  584.  
  585.         if (!$input) {
  586.             return $full;
  587.         }
  588.         if (!preg_match('/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n)/s',$input))  {
  589.             return $full;
  590.         }
  591.         if (!preg_match('/(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s',$input)) {
  592.             return $full;
  593.         }
  594.  
  595.  
  596.         /* this will only replace extends DB_DataObject by default,
  597.             unless use set generator_class_rewrite to ANY or a name*/
  598.  
  599.         $class_rewrite = 'DB_DataObject';
  600.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  601.         if (!($class_rewrite = @$options['generator_class_rewrite'])) {
  602.             $class_rewrite = 'DB_DataObject';
  603.         }
  604.         if ($class_rewrite == 'ANY') {
  605.             $class_rewrite = '[a-z_]+';
  606.         }
  607.  
  608.         $input = preg_replace(
  609.             '/(\n|\r\n)class\s*[a-z0-9_]+\s*extends\s*' .$class_rewrite . '\s*\{(\n|\r\n)/si',
  610.             "\nclass {$this->classname} extends {$this->_extends} \n{\n",
  611.             $input);
  612.  
  613.         return preg_replace(
  614.             '/(\n|\r\n)\s*###START_AUTOCODE(\n|\r\n).*(\n|\r\n)\s*###END_AUTOCODE(\n|\r\n)/s',
  615.             $body,$input);
  616.     }
  617.  
  618.     /**
  619.      * hook to add extra methods to all classes
  620.      *
  621.      * called once for each class, use with $this->table and
  622.      * $this->_definitions[$this->table], to get data out of the current table,
  623.      * use it to add extra methods to the default classes.
  624.      *
  625.      * @access   public
  626.      * @return  string added to class eg. functions.
  627.      */
  628.     function derivedHookFunctions()
  629.     {
  630.         // This is so derived generator classes can generate functions
  631.         // It MUST NOT be changed here!!!
  632.         return "";
  633.     }
  634.  
  635.     /**
  636.      * hook for var lines
  637.      * called each time a var line is generated, override to add extra var
  638.      * lines
  639.      *
  640.      * @param object t containing type,len,flags etc. from tableInfo call
  641.      * @param int padding number of spaces
  642.      * @access   public
  643.      * @return  string added to class eg. functions.
  644.      */
  645.     function derivedHookVar(&$t,$padding)
  646.     {
  647.         // This is so derived generator classes can generate variabels
  648.         // It MUST NOT be changed here!!!
  649.         return "";
  650.     }
  651.  
  652.  
  653.     /**
  654.     * getProxyFull - create a class definition on the fly and instantate it..
  655.     *
  656.     * similar to generated files - but also evals the class definitoin code.
  657.     * 
  658.     * 
  659.     * @param   string database name
  660.     * @param   string  table   name of table to create proxy for.
  661.     * 
  662.     *
  663.     * @return   object    Instance of class. or PEAR Error
  664.     * @access   public
  665.     */
  666.     function getProxyFull($database,$table) {
  667.         
  668.         if ($err = $this->fillTableSchema($database,$table)) {
  669.             return $err;
  670.         }
  671.         
  672.         
  673.         $options = &PEAR::getStaticProperty('DB_DataObject','options');
  674.         $class_prefix  = $options['class_prefix'];
  675.         
  676.         if ($extends = @$options['extends']) {
  677.             $this->_extends = $extends;
  678.             $this->_extendsFile = $options['extends_location'];
  679.         }
  680.  
  681.         
  682.         $classname = $this->classname = $class_prefix.preg_replace('/[^A-Z0-9]/i','_',ucfirst(trim($this->table)));
  683.  
  684.         $out = $this->_generateClassTable();
  685.         //echo $out;
  686.         eval('?>'.$out);
  687.         return new $classname;
  688.         
  689.     }
  690.     
  691.      /**
  692.     * fillTableSchema - set the database schema on the fly
  693.     *
  694.     * 
  695.     * 
  696.     * @param   string database name
  697.     * @param   string  table   name of table to create schema info for
  698.     *
  699.     * @return   none | PEAR::error()
  700.     * @access   public
  701.     */
  702.     function fillTableSchema($database,$table) {
  703.         global $_DB_DATAOBJECT;
  704.         $this->_database  = $database; 
  705.         $this->_connect();
  706.         $table = trim($table);
  707.         
  708.         $__DB= &$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'][$this->_database_dsn_md5];
  709.         
  710.         $defs =  $__DB->tableInfo($table);
  711.         if (PEAR::isError($defs)) {
  712.             return $defs;
  713.         }
  714.         if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 2) {
  715.             $this->debug("getting def for $database/$table",'fillTable');
  716.             $this->debug(print_r($defs,true),'defs');
  717.         }
  718.         // cast all definitions to objects - as we deal with that better.
  719.         
  720.             
  721.         foreach($defs as $def) {
  722.             if (is_array($def)) {
  723.                 $this->_definitions[$table][] = (object) $def;
  724.             }
  725.         }
  726.  
  727.         $this->table = trim($table);
  728.         $ret = $this->_generateDefinitionsTable();
  729.         
  730.         $_DB_DATAOBJECT['INI'][$database][$table] = $ret['table'];
  731.         $_DB_DATAOBJECT['INI'][$database][$table.'__keys'] = $ret['keys'];
  732.         return false;
  733.         
  734.     }
  735.     
  736.  
  737.  
  738. }
  739.